﻿using System;
using System.Collections.Generic;
using System.Linq;
using Icms.Core;
using Icms.Core.Model;
using Icms.Core.Repository;
using Icms.Core.Service;
using Extensions = Icms.Core.Extensions;

namespace Icms.Service
{
    public class CaseService : CrudService<Case>, ICaseService
    {
        private readonly IRepo<Status> statusRepo;
        private readonly IRepo<Party> partyRepo;
        private readonly IParameterRepo _paramParameterRepo;
        private readonly ICaseRepo caseRepo;


        public CaseService(ICaseRepo caseRepo, IRepo<Status> statusRepo, IRepo<Party> partyRepo, IParameterRepo _paramParameterRepo)
            : base(caseRepo)
        {
            this.statusRepo = statusRepo;
            this.partyRepo = partyRepo;
            this._paramParameterRepo = _paramParameterRepo;
            this.caseRepo = caseRepo;
        }

        public override Guid Create(Case c)
        {
            base.Create(c);
            var s = new Status { CaseId = c.Id, Code = Const.CaseStatuses.Entered, DateFrom = DateTime.Now };
            statusRepo.Insert(s);
            statusRepo.Save();
            return c.Id;
        }

        public override void Save(Case e)
        {
            var o = repo.Get(e.Id);
            if (string.IsNullOrEmpty(o.Title) && !string.IsNullOrEmpty(e.Title))
                e.Number = GetNewNumber(o);
            base.Save(e);
        }

        public string GetTitle(Guid id)
        {
            var c = repo.Get(id);
            
            var title = string.Empty;
            var titlevs = string.Empty;

            var parties = partyRepo.Where(o => o.CaseId == id && !o.IsDeleted);

            IEnumerable<Parameter> civilPlantiff;
            IEnumerable<Parameter> defendant;
            IEnumerable<Parameter> appelant;
            IEnumerable<Parameter> versusParty;
            IEnumerable<Parameter> cassationRequestSubmitter;
            IEnumerable<Parameter> reviewer;
            IEnumerable<Parameter> revizuent;
            IEnumerable<Parameter> offender;

            switch (c.TypeId.CaseKind())
            {
                case 1:
                case 4:
                    civilPlantiff = _paramParameterRepo.GetByCode(Const.PartiesCodes.CivilPlantiff);
                    defendant = _paramParameterRepo.GetByCode(Const.PartiesCodes.CivilDefendant);
                    appelant = _paramParameterRepo.GetByCode(Const.PartiesCodes.Appelant);
                    versusParty = _paramParameterRepo.GetByCode(Const.PartiesCodes.VersusPartyCivil);
                    cassationRequestSubmitter = _paramParameterRepo.GetByCode(Const.PartiesCodes.CassationRequestSubmitterCivil);
                    reviewer = _paramParameterRepo.GetByCode(Const.PartiesCodes.Reviewer);

                    title = GetTitlePartByPartyType(civilPlantiff, parties)
                    ?? GetTitlePartByPartyType(appelant, parties)
                    ?? GetTitlePartByPartyType(cassationRequestSubmitter, parties)
                    ?? GetTitlePartByPartyType(reviewer, parties);

                    titlevs = GetTitlePartByPartyType(defendant, parties) ?? GetTitlePartByPartyType(versusParty, parties);
                    break;

                case 2:
                    defendant = _paramParameterRepo.GetByCode(Const.PartiesCodes.PenalDefendant);
                    appelant = _paramParameterRepo.GetByCode(Const.PartiesCodes.Appelant);
                    cassationRequestSubmitter = _paramParameterRepo.GetByCode(Const.PartiesCodes.CassationRequestSubmitter);
                    revizuent = _paramParameterRepo.GetByCode(Const.PartiesCodes.Revizuient);
                    versusParty = _paramParameterRepo.GetByCode(Const.PartiesCodes.VersusPartyPenal);

                    title = GetTitlePartByPartyType(defendant, parties)
                   ?? GetTitlePartByPartyType(appelant, parties)
                   ?? GetTitlePartByPartyType(cassationRequestSubmitter, parties)
                   ?? GetTitlePartByPartyType(revizuent, parties);

                    titlevs = GetTitlePartByPartyType(versusParty, parties);
                    break;
                case 3:
                    offender = _paramParameterRepo.GetByCode(Const.PartiesCodes.ContraventionalOffender);
                    versusParty = _paramParameterRepo.GetByCode(Const.PartiesCodes.VersusPartyConraventional);

                    title = GetTitlePartByPartyType(offender, parties);
                    titlevs = GetTitlePartByPartyType(versusParty, parties);
                    break;
            }

            if (!string.IsNullOrEmpty(title) && !string.IsNullOrEmpty(titlevs))
            {
                title = title + " vs " + titlevs;
            }

            return title;

        }

        private static string GetTitlePartByPartyType(IEnumerable<Parameter> parms, IEnumerable<Party> parties)
        {
            IEnumerable<Party> pp = null;
            if (parms != null && parms.Count() > 0) pp = parties.Where(pt => pt.TypePartyId == parms.FirstOrDefault().Id);

            if (pp != null)
            {
                var party = pp.FirstOrDefault();
                if (party != null && party.Person != null)
                    return Extensions.GetPersonName(party.Person);
            }
            return null;

        }


        public string GetNewNumber(Case caz)
        {
            var min = caseRepo.GetMinNumberInYear(DateTime.Now.Year, caz.CourtId);
            var max = caz.RowRank;
            return string.Format("{0}-{1}-{2}-{3:ddMMyyyy}", caz.Court.Number, caz.Index.Title, ((max - min) + 1), caz.CreatedDate);
        }
    }


}